#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int MOD = 100000000;
int main()
{
	int n, m;
	cin >> n >> m;

	// 读取网格，1表示肥沃，0表示贫瘠
	vector<vector<int>> grid(n, vector<int>(m));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> grid[i][j];
		}
	}

	// DP数组，dp[state]表示轮廓线状态为state时的方案数
	vector<long long> dp(1 << m, 0);
	dp[0] = 1; // 初始状态：无种植

	// 逐格处理
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			vector<long long> new_dp(1 << m, 0); // 新状态数组

			for (int state = 0; state < (1 << m); state++) {
				if (dp[state] == 0)
					continue; // 跳过无效状态

				// 获取轮廓线上方（上一行j列）和左方（当前行j-1列）状态
				int top = (state >> j) & 1; // 上一行同列种植状态
				int left = (j > 0) ? ((state >> (j - 1)) & 1) : 0; // 当前行左边种植状态

				if (grid[i][j] == 0) { // 贫瘠土地，只能不种
					int new_state = state & ~(1 << j); // 将j位置0
					new_dp[new_state] += dp[state];

					new_dp[new_state] %= MOD;
				} else { // 肥沃土地
					// 决策1：不种草
					int new_state = state & ~(1 << j); // 将j位置0
					new_dp[new_state] += dp[state];
					new_dp[new_state] %= MOD;
					// 决策2：种草（需检查相邻约束）
					if (top == 0 && left == 0) {
						new_state = state | (1 << j); // 将j位置1
						new_dp[new_state] += dp[state];
						new_dp[new_state] %= MOD;
					}
					
				}
				
			}
			dp = move(new_dp); // 更新状态，准备处理下一格
		}
	}

	// 统计所有方案总数
	long long total = 0;
	for (int state = 0; state < (1 << m); state++) {
		total += dp[state];
		total %= MOD;
	}

	cout << total << endl;
	return 0;
}